热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

mysql学习|LeetCode数据库简单查询练习

力扣:https:leetcode-cn.com力扣网数据库练习:https:leetcode-cn.comproblemsetdatabase文章目录

力扣:https://leetcode-cn.com/
力扣网数据库练习:https://leetcode-cn.com/problemset/database/

文章目录

        • 175. 组合两个表
          • 题解:
            • 1. LeetCode官方题解
            • 2. 执行时间最快的mysql语句
          • 笔记:on与where的区别
        • 176. 第二高的薪水
          • 题解:
            • 1. LeetCode官方题解
            • 2. 执行时间最快的mysql语句
          • 笔记:关于解题思路与limit、isnull等
        • 177. 第N高的薪水
          • 题解:
            • 1. LeetCode官方题解
            • 2. 执行时间最快的mysql语句
          • 笔记:limit x,y 语句用法
        • 181. 超过经理收入的员工
          • 题解:
            • 1. LeetCode官方题解
            • 2. 执行时间最快的mysql语句
          • 笔记:子查询解法
        • 182. 查找重复的电子邮箱
          • 题解:
            • 1. LeetCode官方题解
            • 2. 执行时间最快的mysql语句
          • 笔记:语句执行顺序
        • 183. 从不订购的客户
          • 题解:
            • 1. LeetCode官方题解
            • 2. 执行时间最快的mysql语句
        • 196. 删除重复的电子邮箱
          • 题解:
            • 1. LeetCode官方题解
            • 2. 执行时间最快的mysql语句
          • 笔记:`You can't specify target table 'Person' for update in FROM clause`
        • 197. 上升的温度
          • 题解:
            • 1. LeetCode官方题解
            • 2. 执行时间最快的mysql语句
          • 笔记:时间函数



练习主要以LeetCode上数据库练习题简单题为例,以下分别提供对应题目的官方题解和在提交列表中执行最快的mysql查询语句。


175. 组合两个表

题目连接:https://leetcode-cn.com/problems/combine-two-tables/

Create table Person (PersonId int, FirstName varchar(255), LastName varchar(255))
Create table Address (AddressId int, PersonId int, City varchar(255), State varchar(255))
Truncate table Person
insert into Person (PersonId, LastName, FirstName) values ('1', 'Wang', 'Allen')
Truncate table Address
insert into Address (AddressId, PersonId, City, State) values ('1', '2', 'New York City', 'New York')

表1: Person

+-------------+---------+
| 列名 | 类型 |
+-------------+---------+
| PersonId | int |
| FirstName | varchar |
| LastName | varchar |
+-------------+---------+

PersonId 是上表主键

表2: Address

+-------------+---------+
| 列名 | 类型 |
+-------------+---------+
| AddressId | int |
| PersonId | int |
| City | varchar |
| State | varchar |
+-------------+---------+

AddressId 是上表主键

编写一个 SQL 查询,满足条件:无论 person 是否有地址信息,都需要基于上述两表提供 person 的以下信息:

FirstName, LastName, City, State

题解:

1. LeetCode官方题解

方法:使用 outer join
算法

因为表 Address 中的 personId 是表 Person 的外关键字,所以我们可以连接这两个表来获取一个人的地址信息。

考虑到可能不是每个人都有地址信息,我们应该使用 outer join 而不是默认的 inner join。

select FirstName, LastName, City, State
from Person left join Address
on Person.PersonId = Address.PersonId
;作者:LeetCode
链接:https://leetcode-cn.com/problems/combine-two-tables/solution/zu-he-liang-ge-biao-by-leetcode/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

注意:如果没有某个人的地址信息,使用 where 子句过滤记录将失败,因为它不会显示姓名信息。

2. 执行时间最快的mysql语句

# Write your MySQL query statement below
select A.FirstName, A.LastName, B.City, B.State
from Person A
left join (select distinct PersonId, City, State from Address) B
on A.PersonId=B.PersonId;

笔记:on与where的区别

数据库在通过连接两张或多张表来返回记录时,都会生成一张中间的临时表,然后再将这张临时表返回给用户。 在使用left jion时,on和where条件的区别如下:

1、on条件是在生成临时表时使用的条件,它不管on中的条件是否为真,都会返回左边表中的记录。

2、where条件是在临时表生成好后,再对临时表进行过滤的条件。这时已经没有left join的含义(必须返回左边表的记录)了,条件不为真的就全部过滤掉

——来自评论: Carl Marx



176. 第二高的薪水

题目链接:https://leetcode-cn.com/problems/second-highest-salary/

Create table If Not Exists Employee (Id int, Salary int)
Truncate table Employee
insert into Employee (Id, Salary) values ('1', '100')
insert into Employee (Id, Salary) values ('2', '200')
insert into Employee (Id, Salary) values ('3', '300')

编写一个 SQL 查询,获取 Employee 表中第二高的薪水(Salary) 。

+----+--------+
| Id | Salary |
+----+--------+
| 1 | 100 |
| 2 | 200 |
| 3 | 300 |
+----+--------+

例如上述 Employee 表,SQL查询应该返回 200 作为第二高的薪水。如果不存在第二高的薪水,那么查询应返回 null。

+---------------------+
| SecondHighestSalary |
+---------------------+
| 200 |
+---------------------+

题解:

1. LeetCode官方题解

方法一:使用子查询和 LIMIT 子句
算法:将不同的薪资按降序排序,然后使用 LIMIT 子句获得第二高的薪资。

SELECT(SELECT DISTINCTSalaryFROMEmployeeORDER BY Salary DESCLIMIT 1 OFFSET 1) AS SecondHighestSalary
;

然而,如果没有这样的第二最高工资,这个解决方案将被判断为 “错误答案”,因为本表可能只有一项记录。为了克服这个问题,我们可以将其作为临时表。

SELECT(SELECT DISTINCTSalaryFROMEmployeeORDER BY Salary DESCLIMIT 1 OFFSET 1) AS SecondHighestSalary
;

方法二:使用 IFNULL 和 LIMIT 子句
解决 “NULL” 问题的另一种方法是使用 “IFNULL” 函数,如下所示。

SELECTIFNULL((SELECT DISTINCT SalaryFROM EmployeeORDER BY Salary DESCLIMIT 1 OFFSET 1),NULL) AS SecondHighestSalary-------------------------------------------------------------------
作者:LeetCode
链接:https://leetcode-cn.com/problems/second-highest-salary/solution/di-er-gao-de-xin-shui-by-leetcode/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

2. 执行时间最快的mysql语句

# Write your MySQL query statement below
select ifNull((select distinct Salary from Employee order by Salary desc limit 1,1),null) as SecondHighestSalary;

笔记:关于解题思路与limit、isnull等

注意:考虑到有重复值的情况,使用distinct 成绩进行成绩去重。

  • 思路一:使用(IRDER BY)将数据降序排列,利用(LIMIT n1,n2)返回 n1~n2间的数据。
    select (select distinct salary from Employee order by salary desc limit 1,1) as SecondHighestSalary;
  • 思路二:使用聚合函数 max(列名) ,获得最高薪水,再将数据降序排列,则第一个小于 max 的数据为第二高分。
    select max(Salary) SecondHighestSalary from employee where salary<(select max(salary) from employee);

mysql语句分析&#xff1a;

  • limit n子句表示查询结果返回前n条数据
  • offset n表示跳过x条语句
  • limit y offset x 分句表示查询结果跳过 x 条数据&#xff0c;读取前 y 条数据
  • 使用limit和offset&#xff0c;降序排列再返回第二条记录可以得到第二大的值。

考虑特殊情况 isnull()

题目要求&#xff0c;如果没有第二高的成绩&#xff0c;返回空值&#xff0c;所以这里用判断空值的函数&#xff08;ifnull&#xff09;函数来处理特殊情况。
ifnull(a,b)函数解释&#xff1a;
如果value1不是空&#xff0c;结果返回a, 如果value1是空&#xff0c;结果返回b
select ifnull((select 子句),null) as &#39;别名&#39;;

select IFNULL((select distinct(Salary) from Employee order by Salary desc limit 1,1),null) as SecondHighestSalary;



177. 第N高的薪水

题目链接&#xff1a;https://leetcode-cn.com/problems/nth-highest-salary/
编写一个 SQL 查询&#xff0c;获取 Employee 表中第 n 高的薪水&#xff08;Salary&#xff09;。

&#43;----&#43;--------&#43;
| Id | Salary |
&#43;----&#43;--------&#43;
| 1 | 100 |
| 2 | 200 |
| 3 | 300 |
&#43;----&#43;--------&#43;

例如上述 Employee 表&#xff0c;n &#61; 2 时&#xff0c;应返回第二高的薪水 200。如果不存在第 n 高的薪水&#xff0c;那么查询应返回 null。

&#43;------------------------&#43;
| getNthHighestSalary(2) |
&#43;------------------------&#43;
| 200 |
&#43;------------------------&#43;

题解&#xff1a;

1. LeetCode官方题解

解题思路

  1. 通过自定义变量&#xff0c;对按薪水降序后的数据进行排名&#xff0c;其中同薪同名&#xff0c;连续排名&#xff0c;即形如1、2、2、3&#xff1b;
  2. 对具有排名信息的临时表二次筛选&#xff0c;得到排名为N的薪水&#xff1b;
  3. 因为薪水排名为N的记录可能不止1个&#xff0c;用distinct去重

CREATE FUNCTION getNthHighestSalary(N INT) RETURNS INT
BEGINRETURN (# Write your MySQL query statement below.SELECT DISTINCT salary FROM (SELECT salary, &#64;r:&#61;IF(&#64;p&#61;salary, &#64;r, &#64;r&#43;1) AS &#39;rank&#39;, &#64;p:&#61; salary FROM employee, (SELECT &#64;r:&#61;0, &#64;p:&#61;NULL)init ORDER BY salary DESC) tmpWHERE rank &#61; N);
END-------------------------------------------------------------------
作者&#xff1a;luanz
链接&#xff1a;https://leetcode-cn.com/problems/nth-highest-salary/solution/mysql-zi-ding-yi-bian-liang-by-luanz/
来源&#xff1a;力扣&#xff08;LeetCode&#xff09;
著作权归作者所有。商业转载请联系作者获得授权&#xff0c;非商业转载请注明出处。

2. 执行时间最快的mysql语句

CREATE FUNCTION getNthHighestSalary(N INT) RETURNS INT
BEGIN
set n &#61; n-1;RETURN (# Write your MySQL query statement below.select distinct Salary from Employee order by Salary desc limit n,1);
END

笔记&#xff1a;limit x,y 语句用法

此题与 176. 第二高的薪水 类型相同&#xff0c;可以使用 limit n1,n2 语句&#xff0c;取n1~n2之间的数据。

另外&#xff0c;对MySQL来说&#xff0c; limit x,y &#61; limit y offset x。
SQL查询语句中的 limit 与 offset 的区别&#xff1a;

  • limit y 分句表示: 读取 y 条数据
  • limit x, y 分句表示: 跳过 x 条数据&#xff0c;读取 y 条数据
  • limit y offset x 分句表示: 跳过 x 条数据&#xff0c;读取 y 条数据

-- 例1&#xff1a;从第0个开始&#xff0c;获取20条数据
select * from testtable limit 0, 20;
select * from testtable limit 20 offset 0;
-- 例2&#xff1a; 从第20个开始&#xff0c;获取20条数据
select * from testtable limit 20, 20;
select * from testtable limit 20 offset 20;
-- 例3&#xff1a; 从第40个开始&#xff0c;获取20条数据
select * from testtable limit 40, 20;
select * from testtable limit 20 offset 40;

——参考自博文&#xff1a; SQL查询语句中的 limit 与 offset 的区别


如此题中&#xff0c;选用第n高的薪水。我们只需先将n设置为n-1&#xff08;表中数据从0开始排列&#xff09;&#xff0c;然后使用 limt n,1 从第n个数据开始获取一条数据即可。

CREATE FUNCTION getNthHighestSalary(N INT) RETURNS INT
BEGINSET N &#61; N - 1;RETURN (# Write your MySQL query statement below.select (select distinct salary from employee order by salary desclimit N,1));
END



181. 超过经理收入的员工

题目链接&#xff1a;https://leetcode-cn.com/problems/employees-earning-more-than-their-managers/

Create table If Not Exists Employee (Id int, Name varchar(255), Salary int, ManagerId int)
Truncate table Employee
insert into Employee (Id, Name, Salary, ManagerId) values (&#39;1&#39;, &#39;Joe&#39;, &#39;70000&#39;, &#39;3&#39;)
insert into Employee (Id, Name, Salary, ManagerId) values (&#39;2&#39;, &#39;Henry&#39;, &#39;80000&#39;, &#39;4&#39;)
insert into Employee (Id, Name, Salary, ManagerId) values (&#39;3&#39;, &#39;Sam&#39;, &#39;60000&#39;, &#39;None&#39;)
insert into Employee (Id, Name, Salary, ManagerId) values (&#39;4&#39;, &#39;Max&#39;, &#39;90000&#39;, &#39;None&#39;)

Employee 表包含所有员工&#xff0c;他们的经理也属于员工。每个员工都有一个 Id&#xff0c;此外还有一列对应员工的经理的 Id。

&#43;----&#43;-------&#43;--------&#43;-----------&#43;
| Id | Name | Salary | ManagerId |
&#43;----&#43;-------&#43;--------&#43;-----------&#43;
| 1 | Joe | 70000 | 3 |
| 2 | Henry | 80000 | 4 |
| 3 | Sam | 60000 | NULL |
| 4 | Max | 90000 | NULL |
&#43;----&#43;-------&#43;--------&#43;-----------&#43;

给定 Employee 表&#xff0c;编写一个 SQL 查询&#xff0c;该查询可以获取收入超过他们经理的员工的姓名。在上面的表格中&#xff0c;Joe 是唯一一个收入超过他的经理的员工。

&#43;----------&#43;
| Employee |
&#43;----------&#43;
| Joe |
&#43;----------&#43;

题解&#xff1a;

1. LeetCode官方题解

方法1&#xff1a;使用 WHERE 语句
算法:

如下面表格所示&#xff0c;表格里存有每个雇员经理的信息&#xff0c;我们也许需要从这个表里获取两次信息。

SELECT *
FROM Employee AS a, Employee AS b
;

注意&#xff1a;关键词 ‘AS’ 是可选的

IdNameSalaryManagerIdIdNameSalaryManagerId
1Joe7000031Joe700003
2Henry8000041Joe700003
3Sam600001Joe700003
4Max900001Joe700003
1Joe7000032Henry800004
2Henry8000042Henry800004
3Sam600002Henry800004
4Max900002Henry800004
1Joe7000033Sam60000
2Henry8000043Sam60000
3Sam600003Sam60000
4Max900003Sam60000
1Joe7000034Max90000
2Henry8000044Max90000
3Sam600004Max90000
4Max900004Max90000

前 3 列来自表格 a &#xff0c;后 3 列来自表格 b

从两个表里使用 Select 语句可能会导致产生 笛卡尔乘积 。在这种情况下&#xff0c;输出会产生 4*4&#61;16 个记录。然而我们只对雇员工资高于经理的人感兴趣。所以我们应该用 WHERE 语句加 2 个判断条件。

SELECT*
FROMEmployee AS a,Employee AS b
WHEREa.ManagerId &#61; b.IdAND a.Salary > b.Salary
;

IdNameSalaryManagerIdIdNameSalaryManagerId
1Joe7000033Sam60000

由于我们只需要输出雇员的名字&#xff0c;所以我们修改一下上面的代码&#xff0c;得到最终解法&#xff1a;

SELECTa.Name AS &#39;Employee&#39;
FROMEmployee AS a,Employee AS b
WHEREa.ManagerId &#61; b.IdAND a.Salary > b.Salary
;

方法 2&#xff1a;使用 JOIN 语句
算法:

实际上&#xff0c; JOIN 是一个更常用也更有效的将表连起来的办法&#xff0c;我们使用 ON 来指明条件。

SELECTa.NAME AS Employee
FROM Employee AS a JOIN Employee AS bON a.ManagerId &#61; b.IdAND a.Salary > b.Salary
;-------------------------------------------------------------------
作者&#xff1a;LeetCode
链接&#xff1a;https://leetcode-cn.com/problems/employees-earning-more-than-their-managers/solution/chao-guo-jing-li-shou-ru-de-yuan-gong-by-leetcode/
来源&#xff1a;力扣&#xff08;LeetCode&#xff09;
著作权归作者所有。商业转载请联系作者获得授权&#xff0c;非商业转载请注明出处。

2. 执行时间最快的mysql语句

以上两种写法&#xff0c;一种是直接对两表

# Write your MySQL query statement below
select e.Name Employee
from Employee e left join (select distinct Id,Salary from Employee) m on e.ManagerId &#61; m.Id
where e.Salary > m.Salary

笔记&#xff1a;子查询解法

官方题解一采用直接对两表进行笛卡尔积&#xff0c;而后对结果使用WHERE筛选出符合条件的数据&#xff0c;官方题解二使用内连接的方式对临时表过滤筛选。除此之外&#xff0c;我们还可以使用子查询语句解决问题。

SELECT Name Employee
FROMEmployee AS e
WHERESalary > (SELECT SalaryFROMEmployeeWHEREId &#61; e.Managerid)



182. 查找重复的电子邮箱

题目链接&#xff1a;https://leetcode-cn.com/problems/duplicate-emails/

Create table If Not Exists Person (Id int, Email varchar(255))
Truncate table Person
insert into Person (Id, Email) values (&#39;1&#39;, &#39;a&#64;b.com&#39;)
insert into Person (Id, Email) values (&#39;2&#39;, &#39;c&#64;d.com&#39;)
insert into Person (Id, Email) values (&#39;3&#39;, &#39;a&#64;b.com&#39;)

编写一个 SQL 查询&#xff0c;查找 Person 表中所有重复的电子邮箱。

示例&#xff1a;

&#43;----&#43;---------&#43;
| Id | Email |
&#43;----&#43;---------&#43;
| 1 | a&#64;b.com |
| 2 | c&#64;d.com |
| 3 | a&#64;b.com |
&#43;----&#43;---------&#43;

根据以上输入&#xff0c;你的查询应返回以下结果&#xff1a;

&#43;---------&#43;
| Email |
&#43;---------&#43;
| a&#64;b.com |
&#43;---------&#43;

说明&#xff1a;所有电子邮箱都是小写字母。

题解&#xff1a;

1. LeetCode官方题解

方法一&#xff1a;使用 GROUP BY 和临时表
算法:

重复的电子邮箱存在多次。要计算每封电子邮件的存在次数&#xff0c;我们可以使用以下代码。

MySQL
select Email, count(Email) as num
from Person
group by Email;

Emailnum
a&#64;b.com2
c&#64;d.com1

以此作为临时表&#xff0c;我们可以得到下面的解决方案。

MySQL
select Email from
(select Email, count(Email) as numfrom Persongroup by Email
) as statistic
where num > 1
;

方法二&#xff1a;使用 GROUP BY 和 HAVING 条件
向 GROUP BY 添加条件的一种更常用的方法是使用 HAVING 子句&#xff0c;该子句更为简单高效。

所以我们可以将上面的解决方案重写为&#xff1a;

MySQL
select Email
from Person
group by Email
having count(Email) > 1;-------------------------------------------------------------------
作者&#xff1a;LeetCode
链接&#xff1a;https://leetcode-cn.com/problems/duplicate-emails/solution/cha-zhao-zhong-fu-de-dian-zi-you-xiang-by-leetcode/
来源&#xff1a;力扣&#xff08;LeetCode&#xff09;
著作权归作者所有。商业转载请联系作者获得授权&#xff0c;非商业转载请注明出处。

2. 执行时间最快的mysql语句

# Write your MySQL query statement below
Select Email from Person
Group by Email
Having Count(Email)>1

笔记&#xff1a;语句执行顺序

在使用group by、having等语句是要注意它们的执行顺序。
执行顺序 &#xff1a;from > on > where > group by > having > select > distinct > order by > top

当一个查询语句同时出现了where,group by,having,order by的时候&#xff0c;执行顺序和编写顺序是&#xff1a;
1.执行where xx对全表数据做筛选&#xff0c;返回第1个结果集。
2.针对第1个结果集使用group by分组&#xff0c;返回第2个结果集。
3.针对第2个结集执行having xx进行筛选&#xff0c;返回第3个结果集。
4.针对第3个结果集中的每1组数据执行select xx&#xff0c;有几组就执行几次&#xff0c;返回第4个结果集。
5.针对第4个结果集排序。

——参考自博文&#xff1a;where、having、group by、order by执行和书写顺序



183. 从不订购的客户

题目链接&#xff1a;https://leetcode-cn.com/problems/customers-who-never-order/

Create table If Not Exists Customers (Id int, Name varchar(255))
Create table If Not Exists Orders (Id int, CustomerId int)
Truncate table Customers
insert into Customers (Id, Name) values (&#39;1&#39;, &#39;Joe&#39;)
insert into Customers (Id, Name) values (&#39;2&#39;, &#39;Henry&#39;)
insert into Customers (Id, Name) values (&#39;3&#39;, &#39;Sam&#39;)
insert into Customers (Id, Name) values (&#39;4&#39;, &#39;Max&#39;)
Truncate table Orders
insert into Orders (Id, CustomerId) values (&#39;1&#39;, &#39;3&#39;)
insert into Orders (Id, CustomerId) values (&#39;2&#39;, &#39;1&#39;)

某网站包含两个表&#xff0c;Customers 表和 Orders 表。编写一个 SQL 查询&#xff0c;找出所有从不订购任何东西的客户。

Customers 表&#xff1a;

&#43;----&#43;-------&#43;
| Id | Name |
&#43;----&#43;-------&#43;
| 1 | Joe |
| 2 | Henry |
| 3 | Sam |
| 4 | Max |
&#43;----&#43;-------&#43;

Orders 表&#xff1a;

&#43;----&#43;------------&#43;
| Id | CustomerId |
&#43;----&#43;------------&#43;
| 1 | 3 |
| 2 | 1 |
&#43;----&#43;------------&#43;

例如给定上述表格&#xff0c;你的查询应返回&#xff1a;

&#43;-----------&#43;
| Customers |
&#43;-----------&#43;
| Henry |
| Max |
&#43;-----------&#43;

题解&#xff1a;

1. LeetCode官方题解

方法&#xff1a;使用子查询和 NOT IN 子句
算法&#xff1a;如果我们有一份曾经订购过的客户名单&#xff0c;就很容易知道谁从未订购过。

我们可以使用下面的代码来获得这样的列表。

select customerid from orders;

然后&#xff0c;我们可以使用 NOT IN 查询不在此列表中的客户。

select customers.name as &#39;Customers&#39;
from customers
where customers.id not in
(select customerid from orders
);-------------------------------------------------------------------
作者&#xff1a;LeetCode
链接&#xff1a;https://leetcode-cn.com/problems/customers-who-never-order/solution/cong-bu-ding-gou-de-ke-hu-by-leetcode/
来源&#xff1a;力扣&#xff08;LeetCode&#xff09;
著作权归作者所有。商业转载请联系作者获得授权&#xff0c;非商业转载请注明出处。

2. 执行时间最快的mysql语句

# Write your MySQL query statement below
select Customers.Name as Customers
from Customers
where Id not in
(select distinct CustomerId from Orders
)



196. 删除重复的电子邮箱

题目链接&#xff1a;https://leetcode-cn.com/problems/delete-duplicate-emails/

编写一个 SQL 查询&#xff0c;来删除 Person 表中所有重复的电子邮箱&#xff0c;重复的邮箱里只保留 Id 最小 的那个。

&#43;----&#43;------------------&#43;
| Id | Email |
&#43;----&#43;------------------&#43;
| 1 | john&#64;example.com |
| 2 | bob&#64;example.com |
| 3 | john&#64;example.com |
&#43;----&#43;------------------&#43;

Id 是这个表的主键。
例如&#xff0c;在运行你的查询语句之后&#xff0c;上面的 Person 表应返回以下几行:

&#43;----&#43;------------------&#43;
| Id | Email |
&#43;----&#43;------------------&#43;
| 1 | john&#64;example.com |
| 2 | bob&#64;example.com |
&#43;----&#43;------------------&#43;

提示&#xff1a;

执行 SQL 之后&#xff0c;输出是整个 Person 表。
使用 delete 语句。


题解&#xff1a;

1. LeetCode官方题解

方法&#xff1a;使用 DELETE 和 WHERE 子句
算法: 我们可以使用以下代码&#xff0c;将此表与它自身在电子邮箱列中连接起来。

SELECT p1.*
FROM Person p1,Person p2
WHEREp1.Email &#61; p2.Email
;

然后我们需要找到其他记录中具有相同电子邮件地址的更大 ID。所以我们可以像这样给 WHERE 子句添加一个新的条件。

SELECT p1.*
FROM Person p1,Person p2
WHEREp1.Email &#61; p2.Email AND p1.Id > p2.Id
;

因为我们已经得到了要删除的记录&#xff0c;所以我们最终可以将该语句更改为 DELETE。

MySQL
DELETE p1 FROM Person p1,Person p2
WHEREp1.Email &#61; p2.Email AND p1.Id > p2.Id-------------------------------------------------------------------
作者&#xff1a;LeetCode
链接&#xff1a;https://leetcode-cn.com/problems/delete-duplicate-emails/solution/shan-chu-zhong-fu-de-dian-zi-you-xiang-by-leetcode/
来源&#xff1a;力扣&#xff08;LeetCode&#xff09;
著作权归作者所有。商业转载请联系作者获得授权&#xff0c;非商业转载请注明出处。

2. 执行时间最快的mysql语句

# Write your MySQL query statement below
DELETE FROM Person
WHERE Id NOT IN
( SELECT P.Id FROM(SELECT MIN(Id) AS IdFROM PersonGROUP BY Email ) AS P
)

笔记&#xff1a;You can&#39;t specify target table &#39;Person&#39; for update in FROM clause

方法二&#xff1a;查询出所有的邮箱的最小Id&#xff0c;则不再此列表中的Id都重复Id。

报错&#xff1a;You can’t specify target table ‘Person’ for update in FROM clause&#xff0c;是因为&#xff1a;
mysql不支持对同一个表进行delete(update)和select操作&#xff0c;必须将查询结果保留进一个新表里&#xff0c;再次select&#xff0c;并且select出的表必须有一个自己的别名。

因此&#xff0c;我们在子查询中的查询到的临时表还需要进行再封装。

SELECT P.Id FROM(SELECT MIN(Id) AS IdFROM PersonGROUP BY Email ) AS P

此表返回的结果集是所有不同邮箱的最小Id&#xff0c;接下来只需找到不再此列表中的Id即是我们需要删去的重复Id。

DELETE FROM Person
WHERE Id NOT IN
( SELECT P.Id FROM(SELECT MIN(Id) AS IdFROM PersonGROUP BY Email ) AS P
)



197. 上升的温度

题目链接&#xff1a;https://leetcode-cn.com/problems/rising-temperature/

Create table If Not Exists Weather (Id int, RecordDate date, Temperature int)
Truncate table Weather
insert into Weather (Id, RecordDate, Temperature) values (&#39;1&#39;, &#39;2015-01-01&#39;, &#39;10&#39;)
insert into Weather (Id, RecordDate, Temperature) values (&#39;2&#39;, &#39;2015-01-02&#39;, &#39;25&#39;)
insert into Weather (Id, RecordDate, Temperature) values (&#39;3&#39;, &#39;2015-01-03&#39;, &#39;20&#39;)
insert into Weather (Id, RecordDate, Temperature) values (&#39;4&#39;, &#39;2015-01-04&#39;, &#39;30&#39;)

给定一个 Weather 表&#xff0c;编写一个 SQL 查询&#xff0c;来查找与之前&#xff08;昨天的&#xff09;日期相比温度更高的所有日期的 Id。

&#43;---------&#43;------------------&#43;------------------&#43;
| Id(INT) | RecordDate(DATE) | Temperature(INT) |
&#43;---------&#43;------------------&#43;------------------&#43;
| 1 | 2015-01-01 | 10 |
| 2 | 2015-01-02 | 25 |
| 3 | 2015-01-03 | 20 |
| 4 | 2015-01-04 | 30 |
&#43;---------&#43;------------------&#43;------------------&#43;

例如&#xff0c;根据上述给定的 Weather 表格&#xff0c;返回如下 Id:

&#43;----&#43;
| Id |
&#43;----&#43;
| 2 |
| 4 |
&#43;----&#43;

题解&#xff1a;

1. LeetCode官方题解

方法&#xff1a;使用 JOIN 和 DATEDIFF() 子句
算法: MySQL 使用 DATEDIFF 来比较两个日期类型的值。

因此&#xff0c;我们可以通过将 weather 与自身相结合&#xff0c;并使用 DATEDIFF() 函数。

MySQL
SELECTweather.id AS &#39;Id&#39;
FROMweatherJOINweather w ON DATEDIFF(weather.date, w.date) &#61; 1AND weather.Temperature > w.Temperature
;-------------------------------------------------------------------
作者&#xff1a;LeetCode
链接&#xff1a;https://leetcode-cn.com/problems/rising-temperature/solution/shang-sheng-de-wen-du-by-leetcode/
来源&#xff1a;力扣&#xff08;LeetCode&#xff09;
著作权归作者所有。商业转载请联系作者获得授权&#xff0c;非商业转载请注明出处。

2. 执行时间最快的mysql语句

# Write your MySQL query statement below
select tmp.Id
from (select Id, &#64;flag :&#61; if((Temperature > &#64;preTemperature and &#64;PreDate &#61; DATE_SUB(RecordDate, INTERVAL 1 DAY)), True, False) as flag, &#64;preTemperature :&#61; Temperature, &#64;PreDate :&#61; RecordDatefrom Weather, (select &#64;flag :&#61; False, &#64;preTemperature :&#61; NULL, &#64;PreDate :&#61; NULL) forder by RecordDate
) tmp
where tmp.flag &#61; 1

# Write your MySQL query statement below
SELECT a.Id
FROM (SELECT w.Id, w.Temperature, if(w.Temperature > &#64;last_TAND datediff(w.RecordDate, &#64;last_D) &#61; 1, 1, 0) AS is_greater, &#64;last_T :&#61; w.Temperature, &#64;last_D :&#61; w.RecordDateFROM Weather w, (SELECT &#64;last_T :&#61; 100, &#64;last_D :&#61; 1) bORDER BY RecordDate ASC
) a
WHERE a.is_greater &#61; 1
ORDER BY a.Id ASC

笔记&#xff1a;时间函数

常用时间函数&#xff1a;

CURDATE()返回当前日期
CURTIME()返回当前时间
NOW()返回当前的日期和时间
UNIX_TIMESTAMP(date)返回日期date的UNIX时间戳
FROM_UNIXTIME返回UNIX时间戳的日期值
WEEK(date)返回日期date为一年中的第几周
YEAR(date)返回日期date的年份
HOUR(time)返回time的小时值
MINUTE(time)返回time的分钟值
MONTHNAME(date)返回date的月份名
DATE_FORMAT(date,fmt)返回按字符串fmt格式化日期date值
DATE_ADD(date,INTERVAL expr type)返回一个日期或时间值加上- -个时间间隔的时间值
DATEDIFF(expr,expr2)返回起始时间expr 和结束时间expr2之间的天数

时间函数&#xff1a;https://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html#function_adddate


推荐阅读
  • MySQL Decimal 类型的最大值解析及其在数据处理中的应用艺术
    在关系型数据库中,表的设计与SQL语句的编写对性能的影响至关重要,甚至可占到90%以上。本文将重点探讨MySQL中Decimal类型的最大值及其在数据处理中的应用技巧,通过实例分析和优化建议,帮助读者深入理解并掌握这一重要知识点。 ... [详细]
  • 本文详细介绍了MySQL数据库的基础语法与核心操作,涵盖从基础概念到具体应用的多个方面。首先,文章从基础知识入手,逐步深入到创建和修改数据表的操作。接着,详细讲解了如何进行数据的插入、更新与删除。在查询部分,不仅介绍了DISTINCT和LIMIT的使用方法,还探讨了排序、过滤和通配符的应用。此外,文章还涵盖了计算字段以及多种函数的使用,包括文本处理、日期和时间处理及数值处理等。通过这些内容,读者可以全面掌握MySQL数据库的核心操作技巧。 ... [详细]
  • 本文介绍了在 Spring Boot 中使用 JPA 进行数据删除操作时遇到的 SQL 错误及其解决方法。错误表现为:删除操作失败,原因是无法打开 JPA EntityManager 以进行事务处理。 ... [详细]
  • importpymysql#一、直接连接mysql数据库'''coonpymysql.connect(host'192.168.*.*',u ... [详细]
  • 本文介绍如何使用 Python 的 DOM 和 SAX 方法解析 XML 文件,并通过示例展示了如何动态创建数据库表和处理大量数据的实时插入。 ... [详细]
  • 本文详细介绍了数据库并发控制的基本概念、重要性和具体实现方法。并发控制是确保多个事务在同时操作数据库时保持数据一致性的关键机制。文章涵盖了锁机制、多版本并发控制(MVCC)、乐观并发控制和悲观并发控制等内容。 ... [详细]
  • php更新数据库字段的函数是,php更新数据库字段的函数是 ... [详细]
  • 开机自启动的几种方式
    0x01快速自启动目录快速启动目录自启动方式源于Windows中的一个目录,这个目录一般叫启动或者Startup。位于该目录下的PE文件会在开机后进行自启动 ... [详细]
  • 数据类型和操作数据表2.1MySQL类型之整型2.2MySQL数据类型之浮点型2.3日期时间型DATE1支持时间:1000年1月1日~9999年12月31日DATETIME ... [详细]
  • 在尝试对 QQmlPropertyMap 类进行测试驱动开发时,发现其派生类中无法正常调用槽函数或 Q_INVOKABLE 方法。这可能是由于 QQmlPropertyMap 的内部实现机制导致的,需要进一步研究以找到解决方案。 ... [详细]
  • PTArchiver工作原理详解与应用分析
    PTArchiver工作原理及其应用分析本文详细解析了PTArchiver的工作机制,探讨了其在数据归档和管理中的应用。PTArchiver通过高效的压缩算法和灵活的存储策略,实现了对大规模数据的高效管理和长期保存。文章还介绍了其在企业级数据备份、历史数据迁移等场景中的实际应用案例,为用户提供了实用的操作建议和技术支持。 ... [详细]
  • 本文介绍了如何利用Shell脚本高效地部署MHA(MySQL High Availability)高可用集群。通过详细的脚本编写和配置示例,展示了自动化部署过程中的关键步骤和注意事项。该方法不仅简化了集群的部署流程,还提高了系统的稳定性和可用性。 ... [详细]
  • MyISAM和InnoDB是MySQL中最为广泛使用的两种存储引擎,每种引擎都有其独特的优势和适用场景。MyISAM引擎以其简单的结构和高效的读取速度著称,适用于以读操作为主、对事务支持要求不高的应用。而InnoDB引擎则以其强大的事务处理能力和行级锁定机制,在需要高并发写操作和数据完整性的场景下表现出色。选择合适的存储引擎应综合考虑业务需求、性能要求和数据一致性等因素。 ... [详细]
  • 寒假作业解析:第三周 2月12日 第7题
    尽快完成之前的练习任务!每日一练2.1 Problem A Laurenty and Shop 的题目要求是选择两条不同的路线以最小化总的等待时间。简要分析:通过对比不同路线的等待时间,可以找到最优解。此问题可以通过动态规划或贪心算法来解决,具体取决于路线的复杂性和约束条件。 ... [详细]
  • 本文详细介绍了在 Oracle 数据库中使用 MyBatis 实现增删改查操作的方法。针对查询操作,文章解释了如何通过创建字段映射来处理数据库字段风格与 Java 对象之间的差异,确保查询结果能够正确映射到持久层对象。此外,还探讨了插入、更新和删除操作的具体实现及其最佳实践,帮助开发者高效地管理和操作 Oracle 数据库中的数据。 ... [详细]
author-avatar
mobiledu2502916347
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有